# -*- coding: utf-8 -*-
'''
Created on 22.4.2011
 Ovládání hardwaru stopek
@author: fox
'''
import serial
from time import time


class FindHw:
    '''Slouží k vyhledání portu'''
    pass #TODO: dodělat v příští verzi


class Hw:
    '''Zajišťuje komunikaci s HW'''
    S=None
    pocita=False
    nahoru=False
    cas=0 #při tomto systémovém čase se na stopkách zobrazí 00:00
    m=0 #počet minut
    s=0 #počet vteřin
    minus=False #má li být aktuálně zobrazeno mínus
    spoj=False
    program=[0,0]#aktuální program
    nextprogram=[0,0] #následující program
    programy=[]
    
    
    def __init__(self):
        '''konstruktor '''
        
        slovnik={"min":0,"sec":0,"minus":False,"beep":False,"zastavit":False,"smer":False}
        cas=[]
        for i in range(4):
            cas.append(slovnik)
        for i in range(8):
            self.programy.append(cas)
        
        

        
 
    def Pripoj(self,port):
        '''pokusí se připojit - vrátí True při úspěchu'''
        try:
            self.S = serial.Serial(port, 600, timeout=4)
        except:
            return False            
        else:
            self.spoj=True
            return True
            
    def Odpoj(self):
        '''Zavře port'''
        self.S.close()
    
    def __del__(self):
        '''destruktor zavře port'''
        self.Odpoj()
    
    def __Send(self,cmd):
        '''pošle příkaz a vrátí odpověď nebo prázdný řetězec při timeoutu'''
        self.S.flush() #vypucujem předchozí věci
        self.S.write(cmd+"\n")
        reply=''
        
        while True:
            znak=self.S.read(1)
            
            if (znak==''):#timeout nedočkali jsme se cr
                reply=''
                break
            
            elif (znak=='\r'):#konec řádku
                break
            
            else:
                reply+=znak
        
        return reply
                    
        
    def Ping(self):
        '''provede ping: 
        True - povedl se jinak False'''
        
        if (self.__Send("Z")=="z"):
            return True
        else:
            return False
            
    def GetStatus(self):
        '''
        Nastaví v objektu směr počítání, jestli se počítá, a následující program
        vrací True=úspěch False=došlo k chybě
        V přídě false budou nejspíše špatně nastavené některé proměnné
        '''
        #I    Vrátí informace o aktuálním stavu ve formátu RDPN ; R = režim 0 stopky běží 1 neběží ; D = Směr počítání 1=nahoru 0=dolů ; P = číslo programu (1-8) ; N číslo času v programu (1-4)
        reply=self.__Send("I")
        if (len(reply)!=4):
            return False
        else:
            if(reply[0]=="0"):
                self.pocita=True
            elif(reply[0]=="1"):
                self.pocita=False
            else:
                return False
            
            if(reply[1]=="0"):
                self.nahoru=False
            elif(reply[1]=="1"):
                self.nahoru=True
            else:
                return False
            
            try:
                self.program[0]=int(reply[2])#program
                self.program[1]=int(reply[3])#číslo času
                
                #todo: přidat ochranu na elikost hodnot    
            except:
                self.program=[-1,-1]
                return False
            
            return True
            
    def GetTime(self):
        reply=self.__Send("T")
        if (len(reply)==4):
            try:
                minuty=int(reply[:2])
                sekundy=int(reply[2:])
            except:
                return False
            
         
            if(self.pocita):
                cas=float(60*minuty+sekundy)
                if(self.nahoru):
                    cas=time()-cas
                else:
                    cas=time()+cas
                self.cas=int(cas)
            else:
                self.m=minuty
                self.s=sekundy
            return True
        else:
            return False
                       
    def Time(self):
        '''Vrátí řetězec času stopek založený  na poslední zjištěné hodnotě'''
    
        if(self.pocita):
            now=abs(self.cas-int(time()))
            
            M=now/60

            S=now%60
                
            return [M,S]
        else: #nepočítáme
            return [self.m,self.s]
     
    def StartStop(self):
        '''
        Funguje jako tlačítko start/stop
        zění stav stopek a poté přenastaví aktuální stav v objektu
        při úspěchu vrací True jinak False
        '''
        reply=self.__Send("S")
        if(reply=="0"):
            self.pocita=True
        elif(reply=="1"):
            self.pocita=False
        else:
            return False
        
        return True  
    
    def GetProg(self,p,c):
        '''natáhne program , cas'''
        reply=self.__Send("R"+str(p)+str(c))
        if (len(reply)==7):
            try:
                self.programy[p-1][c-1]={"min":int(reply[3:5]),"sec":int(reply[5:7]),"minus":bool(reply[0]),"beep":bool(reply[2]),"zastavit":bool(reply[1])}
            except:
                print ("---"+reply)
                return False
            print ("+++"+reply)
            return True
            
        else:
            return False
        

    
            
    
    
    
#dev=Hw("/dev/ttyUSB1") 